GAMES101

您所在的位置:网站首页 games 101作业三 GAMES101

GAMES101

2024-01-04 19:28| 来源: 网络整理| 查看: 265

前言

由于上个月CSDN无故告诉我我的原创文章侵权(原创也侵权?),且我多日内多次申诉无效,于是我没有再更新自己的博客。今天我上CSDN的时候自己的文章(没有任何更改,莫名其妙就不侵权了?)又突然通过了,想着还是把这个系列更新完吧,不能半途而废。

上篇作业4

本篇继续更新作业5相关内容

作业5相关链接

games的作业5链接

我的源码

作业5简述

使用光线追踪渲染图像

作业5相关知识笔记

Whitted-Style Ray Tracing(Soft shadows、Glossy reflection、Indirect illumination)克拉默法则Axis-Aligned Bounding Box(AABB)

作业5思路

1.main函数梳理

可以看到main函数中新建了1280*960的场景以及定义两个sphere、一个mesh以及它们的材质颜色和两个光源。至于它们怎么实现的,分别写在了对应的c++文件中。

关于std::move(),我觉得知乎上这篇讲右值引用很好,或者参照《C++Premier》进行理解。

2.实现Reder()

首先要实现光线的生成,注意这里要对应到每个像素。而原Reder()中对应i,j为每个单位高度/宽度,我们要将i,j转化到单位像素上去。

原来scene内width应为(0,width-1),height应为(height -1,0)(从左上角开始遍历),而且在上面我们将scene进行了压缩到了[-1,1]的范围空间,所以这里i,j也要进行压缩,还原时也要乘上相应系数。查看原理

void Renderer::Render(const Scene& scene) { std::vector framebuffer(scene.width * scene.height); float scale = std::tan(deg2rad(scene.fov * 0.5f)); float imageAspectRatio = scene.width / (float)scene.height; // Use this variable as the eye position to start your rays. Vector3f eye_pos(0); int m = 0; for (int j = 0; j < scene.height; ++j) { for (int i = 0; i < scene.width; ++i) { // generate primary ray direction float x; float y; // TODO: Find the x and y positions of the current pixel to get the direction // vector that passes through it. // Also, don't forget to multiply both of them with the variable *scale*, and // x (horizontal) variable with the *imageAspectRatio* x = (((i + 0.5) / ((float)scene.width) * 2)-1) * imageAspectRatio * scale; y = (1 - (j + 0.5) / (float)scene.height * 2 )* scale ; Vector3f dir = normalize(Vector3f(x, y, -1)); // Don't forget to normalize this direction! framebuffer[m++] = castRay(eye_pos, dir, scene, 0); } UpdateProgress(j / (float)scene.height); } // save framebuffer to file FILE* fp = fopen("binary.ppm", "wb"); (void)fprintf(fp, "P6\n%d %d\n255\n", scene.width, scene.height); for (auto i = 0; i < scene.height * scene.width; ++i) { static unsigned char color[3]; color[0] = (char)(255 * clamp(0, 1, framebuffer[i].x)); color[1] = (char)(255 * clamp(0, 1, framebuffer[i].y)); color[2] = (char)(255 * clamp(0, 1, framebuffer[i].z)); fwrite(color, 1, 3, fp); } fclose(fp); }

3.实现 rayTriangleIntersect()

这个公式课程中已经推导过了。 在这里插入图片描述

值得注意的是,在判断条件那里,如果用1-u-v >=0 ,会出现蓝点 ,当你打印出来蓝点坐标时,会发现其正好为最大的负值浮点数,这是因为u,v正好在三角形交界与射线交点处。所以这里我更改了判断条件。

bool rayTriangleIntersect(const Vector3f& v0, const Vector3f& v1, const Vector3f& v2, const Vector3f& orig, const Vector3f& dir, float& tnear, float& u, float& v) { // TODO: Implement this function that tests whether the triangle // that's specified bt v0, v1 and v2 intersects with the ray (whose // origin is *orig* and direction is *dir*) // Also don't forget to update tnear, u and v. Vector3f E1 = v1 - v0; Vector3f E2 = v2 - v0; Vector3f S = orig - v0; Vector3f S1 = crossProduct(dir,E2); Vector3f S2 = crossProduct(S,E1); float temp = dotProduct(E1,S1); if(temp == 0 || temp = 0 && v >= 0 && tnear >= 0 && (1 - u -v) >= -__FLT_EPSILON__) { return true; } else{ //if(u >= 0 && v >= 0 && tnear >= 0 &&(1 - u -v) < 0) //std::cout


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3